package idv.takeshi.software.productline.bookstore.domain.model.book;

import java.math.BigDecimal;

import javax.persistence.Column;
import javax.persistence.Embeddable;
import javax.persistence.Entity;

import org.apache.commons.lang.Validate;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;

/**
 * A model class which is one kind of promotion, setPrice.
 * @author takeshi
 *
 */
@Entity
public class SetPrice extends Promotion {
	
	@Column(name = "SET_PRICE")
	private BigDecimal setPrice = new BigDecimal("0");
	
	/**
	 * @return the setPrice
	 */
	public BigDecimal getSetPrice() {
		return setPrice;
	}

	/**
	 * Set setPrice.
	 * Here are two check rules before setting the setPrice<br>
	 * <ol>
	 * 	<li>setPrice shall not small than 0</li>
	 * 	<li>setPrice shall not greater than fixedPrice</li>
	 * </ol>
	 * @param setPrice the setPrice to set
	 * @param book 
	 * @throws SetPriceSettingException if above check rules violated.
	 */
	public void setSetPrice(BigDecimal setPrice, Book book) throws SetPriceSettingException {
		Validate.notNull(setPrice, "setPrice shall always not be null");
		BigDecimal fixedPrice = getFixedPrice(book);
		if(setPrice.compareTo(fixedPrice) > 0){
			throw new SetPriceGreaterThanFixedPriceException("setPrice:" + setPrice +
					" shall small than or equals to fixedPrice:" + fixedPrice);
		}
		if(setPrice.compareTo(new BigDecimal("0")) < 0){
			throw new SetPriceSmallThanZeroException("setPrice:" + setPrice +
					" shall greater than 0");
		}
		this.setPrice = setPrice;
	}

	/**
	 * Calculate a promoted price by setPrice algorithm.
	 * @param book
	 * @return calculated price
	 */
	@Override
	public BigDecimal getPromotedPrice(Book book) {
		//check for book and corresponding fixedPrice shall not be null
		@SuppressWarnings("unused")
		BigDecimal fixedPrice = getFixedPrice(book);
		return setPrice;
	}

	/* (non-Javadoc)
	 * @see idv.takeshi.software.productline.bookstore.domain.model.book.Promotion#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (obj == null) { return false; }
		   if (obj == this) { return true; }
		   if (obj.getClass() != getClass()) {
		     return false;
		   }
		   SetPrice rhs = (SetPrice) obj;
		   return new EqualsBuilder()
		   	   .appendSuper(super.equals(rhs))
			   .append(this.setPrice, rhs.setPrice)
		       .isEquals();
	}

	/* (non-Javadoc)
	 * @see idv.takeshi.software.productline.bookstore.domain.model.book.Promotion#hashCode()
	 */
	@Override
	public int hashCode() {
		return new HashCodeBuilder(61, 97).
		   appendSuper(super.hashCode()).
	       append(this.setPrice).
	       toHashCode();
	}
 
}
 
